﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace FMS.Formulation.Licensing.Engine
{

    internal class Encryption
    {
        private const string FMSLICENSEENCODINGKEY1 = "JlQ7JJR7ToO1/RUegJyGRLm2wYBMblfz";

        private const string FMSLICENSEENCODINGIV1 = "0K/tGcQLHtM=";

        private const string FMSLICENSEENCODINGKEY2 = "yMkPVmj8twjV4wnryUs/JYC4wpze40Em";

        private const string FMSLICENSEENCODINGIV2 = "hb2z8sthTn8=";

        private byte[] Key(int Index)
        {
            if (Index == 0)
            {
                return Convert.FromBase64String("JlQ7JJR7ToO1/RUegJyGRLm2wYBMblfz");
            }
            return Convert.FromBase64String("yMkPVmj8twjV4wnryUs/JYC4wpze40Em");
        }

        private byte[] IV(int Index)
        {
            if (Index == 0)
            {
                return Convert.FromBase64String("0K/tGcQLHtM=");
            }
            return Convert.FromBase64String("hb2z8sthTn8=");
        }

        public string EncodeString(string inString, int KeyIndex)
        {
            try
            {
                SymmetricAlgorithm symmetricAlgorithm = SymmetricAlgorithm.Create("TripleDES");
                UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
                symmetricAlgorithm.Key = Key(KeyIndex);
                symmetricAlgorithm.IV = IV(KeyIndex);
                ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateEncryptor();
                byte[] bytes = unicodeEncoding.GetBytes(inString);
                byte[] inArray = cryptoTransform.TransformFinalBlock(bytes, 0, bytes.Length);
                return Convert.ToBase64String(inArray);
            }
            catch
            {
                return string.Empty;
            }
        }

        public string EncodeByteArray(byte[] inpArray, int KeyIndex)
        {
            try
            {
                SymmetricAlgorithm symmetricAlgorithm = SymmetricAlgorithm.Create("TripleDES");
                UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
                symmetricAlgorithm.Key = Key(KeyIndex);
                symmetricAlgorithm.IV = IV(KeyIndex);
                ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateEncryptor();
                byte[] inArray = cryptoTransform.TransformFinalBlock(inpArray, 0, inpArray.Length);
                return Convert.ToBase64String(inArray);
            }
            catch
            {
                return string.Empty;
            }
        }

        public string DecodeString(string inString, int KeyIndex)
        {
            try
            {
                SymmetricAlgorithm symmetricAlgorithm = SymmetricAlgorithm.Create("TripleDES");
                UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
                symmetricAlgorithm.Key = Key(KeyIndex);
                symmetricAlgorithm.IV = IV(KeyIndex);
                ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateDecryptor();
                byte[] array = Convert.FromBase64String(inString);
                byte[] bytes = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
                return unicodeEncoding.GetString(bytes);
            }
            catch
            {
                return string.Empty;
            }
        }

        public byte[] DecodeStringToByteArray(string inString, int KeyIndex)
        {
            byte[] result = new byte[0];
            try
            {
                SymmetricAlgorithm symmetricAlgorithm = SymmetricAlgorithm.Create("TripleDES");
                UnicodeEncoding unicodeEncoding = new UnicodeEncoding();
                symmetricAlgorithm.Key = Key(KeyIndex);
                symmetricAlgorithm.IV = IV(KeyIndex);
                ICryptoTransform cryptoTransform = symmetricAlgorithm.CreateDecryptor();
                byte[] array = Convert.FromBase64String(inString);
                result = cryptoTransform.TransformFinalBlock(array, 0, array.Length);
                return result;
            }
            catch
            {
            }
            return result;
        }

        public byte[] ComputeMD5Hash(byte[] inputByte)
        {
            MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
            return mD5CryptoServiceProvider.ComputeHash(inputByte);
        }

        public string ComputeMD5HashString(byte[] inputByte)
        {
            MD5CryptoServiceProvider mD5CryptoServiceProvider = new MD5CryptoServiceProvider();
            return Convert.ToBase64String(mD5CryptoServiceProvider.ComputeHash(inputByte));
        }

        public string Encrypt3DES(string input, string keySeed)
        {
            ASCIIEncoding aSCIIEncoding = new ASCIIEncoding();
            string s = MD5SUM(Encoding.ASCII.GetBytes(keySeed)).Substring(0, 24);
            input = input.Trim();
            TripleDES tripleDES = TripleDES.Create();
            tripleDES.Padding = PaddingMode.Zeros;
            tripleDES.Mode = CipherMode.ECB;
            tripleDES.Key = aSCIIEncoding.GetBytes(s);
            tripleDES.GenerateIV();
            MemoryStream memoryStream = new MemoryStream();
            CryptoStream cryptoStream = new CryptoStream(memoryStream, tripleDES.CreateEncryptor(), CryptoStreamMode.Write);
            cryptoStream.Write(aSCIIEncoding.GetBytes(input), 0, aSCIIEncoding.GetByteCount(input));
            cryptoStream.FlushFinalBlock();
            byte[] array = memoryStream.ToArray();
            memoryStream.Close();
            cryptoStream.Close();
            return Convert.ToBase64String(array, 0, array.GetLength(0)).Trim();
        }

        public string Decrypt3DES(string input, string keySeed)
        {
            ASCIIEncoding aSCIIEncoding = new ASCIIEncoding();
            string s = MD5SUM(Encoding.ASCII.GetBytes(keySeed)).Substring(0, 24);
            TripleDES tripleDES = TripleDES.Create();
            tripleDES.Padding = PaddingMode.Zeros;
            tripleDES.Mode = CipherMode.ECB;
            tripleDES.Key = aSCIIEncoding.GetBytes(s);
            byte[] array = Convert.FromBase64String(input);
            MemoryStream stream = new MemoryStream(array, 0, array.Length);
            ICryptoTransform transform = tripleDES.CreateDecryptor();
            CryptoStream stream2 = new CryptoStream(stream, transform, CryptoStreamMode.Read);
            StreamReader streamReader = new StreamReader(stream2);
            return streamReader.ReadToEnd();
        }

        private string MD5SUM(byte[] fileOrText)
        {
            return BitConverter.ToString(new MD5CryptoServiceProvider().ComputeHash(fileOrText)).Replace("-", "").ToLower();
        }
    }

}
